/**
 * <p>Title: AuthoritySvcImpl</p>
 * <p>Description: The Interface Implements of Authority Svc</p>
 * <p>Copyright: Shanghai Batchsight Pharmaceutical Technologies, Inc. Copyright(c) 2016</p>
 * @author Huang Zhongwei
 * @version 1.0
 * <pre>Histroy:
 *       2016-9-18  Huang Zhongwei  Create
 *</pre>
*/
package cn.jhg.account.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import cn.jhg.account.entity.AuditTrailObject;
import cn.jhg.account.entity.AuditTrailRecord;
import cn.jhg.account.entity.AuditTrailType;
import cn.jhg.account.entity.Authority;
import cn.jhg.account.entity.UserGroup;
import cn.jhg.account.persist.AuthorityDao;
import cn.jhg.account.persist.UserGroupDao;
import cn.jhg.account.service.AuditTrailSvc;
import cn.jhg.account.util.SequenceProducer;
import cn.jhg.account.util.ServiceResult;
import cn.jhg.account.util.SymbolChange;
/**
 * <p>AuthoritySvcImpl</p>
 * <P>Description:对于用户的权限的增、删、改、查等操作</p>
 * <p>Copyright:版权声明</p>
 * <p>Company: 公司名称</p>
 * @author Huang Zhong wei and Chen Wei
 * @version 1.0
 * <pre>Histroy:
 *       2016-10-18  Huang Zhong wei  Create
 *       2016-12-19  Chen Wei 
 * </pre>
 */
@Service("authoritySvc")
@Transactional
public class AuthoritySvcImpl implements AuthoritySvc{

	@Resource
	private AuthorityDao authorityDao;//注入dao
	@Resource
	private SequenceProducer sequenceProducer;//注入模拟序列类
	@Resource
	private AuditTrailSvc auditTrailSvc;//注入审计追踪
	@Resource
	private UserGroupDao userGroupDao;//注入UserGroupDao
	Logger logger=LoggerFactory.getLogger(AuthoritySvcImpl.class);
	/**
	 * <p>Function: addAuthority</p>
	 * <p>Description:  	新增权限</p>
	 * @param Authority     权限对象
	 * @param iuid  调用者 id
	 * @return ServiceResult<Integer>	封装结果类对象
	 * errorcode：int 错误代码
	 * data：<T> 数据  int id
	 */
	@Override
	public ServiceResult<Integer> addAuthority(Authority au,int sid,int iuid) {
		ServiceResult<Integer> result=new ServiceResult<Integer>();
		try{
			Authority a=authorityDao.getAuthority(au.getName());
			System.out.println(a);
			if(a==null){
				int id=sequenceProducer.nextval("t_ibcp_authority");
				au.setId(id);
				authorityDao.addAuthority(au);
				result.setData(id);
				result.setErrorCode(0);
				logger.info("[INF221722455] addAuthority成功！");
				
				// 添加审计追踪记录
				AuditTrailRecord atRecord = new AuditTrailRecord();
				atRecord.setSid(sid); // 签名 id
				atRecord.setUid(iuid); // 用户 id
				atRecord.setLid(100);
				atRecord.setTid(AuditTrailType.AddAuthority.GetId()); // 审计追踪类型 id
				atRecord.setOtid(AuditTrailObject.Authority.getId());    // 审计追踪对象 id
		
				Document metadata = new Document(); // 审计追踪元数据
				metadata.append("AuthorityId",id);
				metadata.append("AuthorityName",au.getName());
				atRecord.setMeta(metadata);
				auditTrailSvc.addRecord(atRecord);
			}else{
				result.setErrorCode(217663556);//添加权限失败，权限已存在
				logger.error("[ERR217663556] 添加权限失败，权限已存在");
			} //if..else 结束
			return result;
		}catch(Exception e){//try 语句结束
			result.setErrorCode(220083490);
			logger.error("[ERR220083490] 添加权限失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	}
	
	/**
	 * <p>Function: deleteAuthority</p>
	 * <p>Description:  	删除权限</p>
	 * @param auid     		权限对象ID
	 * @param iuid  调用者 id
	 * @return ServiceResult<Integer>	封装结果类对象
	 * errorcode：int 错误代码
	 * data：<T> 数据 null
	 */
	@Override
	public ServiceResult<Integer> deleteAuthority(int auid,int sid, int iuid) {
		ServiceResult<Integer> result=new ServiceResult<Integer>();
		try{
			Authority au=authorityDao.getAuthorityById(auid);
			if(au==null){
				result.setErrorCode(217664657);//删除权限失败，无此权限
				logger.error("[ERR217664657] 删除权限失败，无此权限");
			}else{
				authorityDao.deleteAuthority(auid);
				authorityDao.deleteUgAuthority(auid);
				result.setErrorCode(0);
				logger.info("[INF221722723] deleteAuthority成功！");
				
				// 添加审计追踪记录
				AuditTrailRecord atRecord = new AuditTrailRecord();
				atRecord.setSid(sid); // 签名 id
				atRecord.setUid(iuid); // 用户 id
				atRecord.setLid(100);
				atRecord.setTid(AuditTrailType.DeleteAuthority.GetId()); // 审计追踪类型 id
				atRecord.setOtid(AuditTrailObject.Authority.getId());    // 审计追踪对象 id
	
				Document metadata = new Document(); // 审计追踪元数据
				metadata.append("AuthorityId",auid);
				metadata.append("AuthorityName",au.getName());
				atRecord.setMeta(metadata);
				auditTrailSvc.addRecord(atRecord);
			} // if..else 结束
			return result;
		}catch(Exception e){//try 语句结束
			result.setErrorCode(220084499);
			logger.error("[ERR220084499] 删除权限失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	}
	
	/**
	 * <p>Function: updateAuthority</p>
	 * <p>Description:  	更新权限</p>
	 * @param Authority     权限对象
	 * @param iuid  调用者 id
	 * @return ServiceResult<Integer>	封装结果类对象
	 * errorcode：int 错误代码
	 * data：<T> 数据 null
	 */
	@Override
	public ServiceResult<Integer> updateAuthority(Authority au,int sid, int iuid) {
		ServiceResult<Integer> result=new ServiceResult<Integer>();
		try{
			String name=au.getName();
			Authority nau=authorityDao.getAuthority(name);
			if(nau==null||au.getId()==nau.getId()){
				authorityDao.updateAuthority(au);
				result.setErrorCode(0);
				logger.info("[INF221722761] updateAuthority成功！");
				
				// 添加审计追踪记录
				AuditTrailRecord atRecord = new AuditTrailRecord();
				atRecord.setSid(sid); // 签名 id
				atRecord.setUid(iuid); // 用户 id
				atRecord.setLid(100);
				atRecord.setTid(AuditTrailType.UpdateAuthority.GetId()); // 审计追踪类型 id
				atRecord.setOtid(AuditTrailObject.Authority.getId());    // 审计追踪对象 id
	
				Document metadata = new Document(); // 审计追踪元数据
				metadata.append("AuthorityId",au.getId());
				metadata.append("AuthorityName",au.getName());
				atRecord.setMeta(metadata);
				auditTrailSvc.addRecord(atRecord);
			}else{
				result.setErrorCode(217664941);//更新权限失败，权限名已存在
				logger.error("[ERR217664941] 更新权限失败，权限名已存在");
			} //if..else 结束
			return result;
		}catch(Exception e){//try 语句结束
			result.setErrorCode(220084570);
			logger.error("[ERR220084570] 更新权限失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
		
	}
	
	/**
	 * <p>Function: queryAuthority</p>
	 * <p>Description:  	按用户组 ID 查询权限</p>
	 * @param ugid     		用户组ID
	 * @return ServiceResult<Integer>	封装结果类对象
	 * errorcode：int 错误代码
	 * data：<T> 数据 Set<Integer>		
	 */
	@Override
	public ServiceResult<List<Integer>> queryAuthority(int ugid, int iuid) {
		ServiceResult<List<Integer>> result=new ServiceResult<List<Integer>>();
		try{
			List<Integer> set=authorityDao.queryAuthority(ugid);
			result.setErrorCode(0);
			result.setData(set);
			logger.info("[INF221722827] queryAuthority成功！");
			return result;
		}catch(Exception e){
			result.setErrorCode(220084653);
			logger.error("[ERR220084653] 查询用户组权限失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	}

	/**
	 * <p>Function: queryAuthority</p>
	 * <p>Description:  	按用户组 ID 查询权限</p>
	 * @param ugid     		用户组ID
	 * @param iuid  调用者 id
	 * @return ServiceResult<Integer>	封装结果类对象
	 * errorcode：int 错误代码
	 * data：<T> 数据 Set<Integer>		
	 */
	@Override
	public ServiceResult<List<Authority>> queryAuthoritys(int ugid, int iuid) {
		ServiceResult<List<Authority>> result=new ServiceResult<List<Authority>>();
		try{
			List<Authority> set=authorityDao.queryAuthoritys(ugid);
			result.setErrorCode(0);
			result.setData(set);
			logger.info("[INF221722827] queryAuthority成功！");
			return result;
		}catch(Exception e){
			result.setErrorCode(220084653);
			logger.error("[ERR220084653] 查询用户组权限失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	}
	
	/**
	 * <p>Function: findAuthorityByName</p>
	 * <p>Description:  	按name模糊查询权限</p>
	 * @param name     		权限名称
	 * @param iuid  调用者 id
	 * @return ServiceResult<Authority>	封装结果类对象
	 * errorcode：int 错误代码
	 * data：<T> 数据 list<Authority>		
	 */
	@Override
	public ServiceResult<List<Authority>> findAuthorityByName(String name, int iuid) {
		ServiceResult<List<Authority>> result=new ServiceResult<List<Authority>>();
		try{
			name="%"+name+"%";
			List<Authority> set=authorityDao.findAuthorityByName(name);
			result.setErrorCode(0);
			result.setData(set);
			logger.info("[INF222055667] findAuthorityByName成功！");
			return result;
		}catch(Exception e){
			result.setErrorCode(222055669);
			logger.error("[ERR222055669] name模糊查询权限失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	}
	
	/**
	 * <p>Function: getAuthorityById</p>
	 * <p>Description:  	按id查询权限</p>
	 * @param id     		权限id
	 * @param iuid  调用者 id
	 * @return ServiceResult<Authority>	封装结果类对象
	 * errorcode：int 错误代码
	 * data：<T> 数据 Authority		
	 */
	@Override
	public ServiceResult<Authority> getAuthorityById(int id, int iuid) {
		ServiceResult<Authority> result=new ServiceResult<Authority>();
		try{
			Authority au=authorityDao.getAuthorityById(id);
			if(au==null){
				result.setErrorCode(222059417);
				logger.error("[ERR222059417] 此id权限不存在");
			}else{
				result.setErrorCode(0);
				result.setData(au);
				logger.info("[INF222059420] queryAuthority成功！");
			}
			return result;
		}catch(Exception e){
			result.setErrorCode(222059531);
			logger.error("[ERR222059531] id查询权限失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	}
	
	/**
	 * <p>Function: queryAuthorityExists</p>
	 * <p>Description:  	按ugid查询用户组之外的权限</p>
	 * @param ugid     		用户组id
	 * @param iuid  调用者 id
	 * @return ServiceResult<Set<Authority>>	封装结果类对象
	 * errorcode：int 错误代码
	 * data：<T> 数据list<Authority>		
	 */
	@Override
	public ServiceResult<List<Authority>> queryAuthorityExists(int ugid, int iuid) {
		ServiceResult<List<Authority>> result=new ServiceResult<List<Authority>>();
		try{
			List<Authority> set=authorityDao.queryAuthorityExists(ugid);
			result.setErrorCode(0);
			result.setData(set);
			logger.info("[INFO222059581] 查找用户组之外权限成功");
			return result;
		}catch(Exception e){
			result.setErrorCode(222063062);
			logger.error("[ERR222063062] 查找用户组之外的权限失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	}
	
	/**
	 * 在用户组中添加权限
	 * @param ugid  用户组 id
	 * @param sid 	签名ID
	 * @param auid  权限id
	 * @param iuid  调用者 id
	 * @return	ErrorCode
	 */
	@Override
	public ServiceResult<Integer> addUserGroupAuthority(int ugid,int sid, List<Integer> auid, int iuid) {
		ServiceResult<Integer> result=new ServiceResult<Integer> ();
		Map<String,Integer> map=new HashMap<String,Integer>();
		try{
			if(auid==null||auid.size()==0){
				result.setErrorCode(0);
			}else {
				List<Integer> set=authorityDao.queryAuthority(ugid);
				for(int i:auid){
					if(set==null||set.contains(i)){
						logger.info("[INF221816243] addMember成功！");
					}else{
						map.put("ugid",ugid);
						map.put("aid",i);
						List<Authority> authorityBefore=authorityDao.queryAuthoritys(ugid);
						authorityDao.addUserGroupAuthority(map);
						logger.info("[INF221816243] addMember成功！");
						
						// 添加审计追踪记录
						AuditTrailRecord atRecord = new AuditTrailRecord();
						atRecord.setSid(sid); // 签名 id
						atRecord.setUid(iuid); // 用户 id
						atRecord.setLid(100);
						atRecord.setTid(AuditTrailType.AddUserGroupAuthority.GetId()); // 审计追踪类型 id
						atRecord.setOtid(AuditTrailObject.Authority.getId());    // 审计追踪对象 id
						UserGroup userGroup=userGroupDao.getUserGroupById(ugid);
						List<Authority> authorityAfter=authorityDao.queryAuthoritys(ugid);
						
						Document metadata = new Document(); // 审计追踪元数据
						metadata.append("GroupId",ugid);
						metadata.append("GroupName",userGroup.getName());
						metadata.append("authorityBefore",authorityBefore);
						metadata.append("authorityAfter",authorityAfter);
						atRecord.setMeta(metadata);
						auditTrailSvc.addRecord(atRecord);
					} //if(set==null||set.contains(i)){}else 结束
					result.setErrorCode(0);
				} // for循环结束
			} // if(auid==null||auid.size()==0){}else 结束
			return result;
		}catch(Exception e){//try 语句结束
			result.setErrorCode(222069731);
			logger.error("[ERR222069731] 组添加权限失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	} // 方法结束
	
	/**
	 * <p>Function: deleteUserGroupAuthority</p>
	 * <p>Description:  	删除此ugid用户组的某些权限</p>
	 * @param ugid     		用户组id
	 * @param sid 			签名id
	 * @param aidList     	要删除的权限数组
	 * @param iuid  调用者 id
	 * @return ServiceResult<Integer>	errorcode：int 错误代码
	 */
	@Override
	public ServiceResult<Integer> deleteUserGroupAuthority(int ugid, List<Integer> aidList,int sid, int iuid) {
		ServiceResult<Integer> proxyResult = new ServiceResult<Integer>();
		try {
			List<Integer> aidSet=authorityDao.queryAuthority(ugid);//获取此用户组的所有权限
			Map<String,Integer> map=new HashMap<String,Integer>();
			for(int i:aidList){//遍历aidList,获取aid
				int aid=i;
				if(aidSet.contains(aid)){
					map.put("aid",aid);
					map.put("ugid", ugid);
					authorityDao.deleteUserGroupAuthority(map);
					proxyResult.setErrorCode(0);//删除此权限成功
					logger.info("[INF222072260] deleteUserGroupAuthority成功！");
					
					// 添加审计追踪记录
					AuditTrailRecord atRecord = new AuditTrailRecord();
					atRecord.setSid(sid); // 签名 id
					atRecord.setUid(iuid); // 用户 id
					atRecord.setLid(100);//位置id  测试*********
					atRecord.setTid(AuditTrailType.DeleteUserGroupAuthority.GetId()); // 审计追踪类型 id
					atRecord.setOtid(AuditTrailObject.Authority.getId());    // 审计追踪对象 id

					Document metadata = new Document(); // 审计追踪元数据
					metadata.append("UserGroupId",ugid);
					UserGroup userGroup=userGroupDao.getUserGroupById(ugid);
					List<Authority> authorityAfter=authorityDao.queryAuthoritys(ugid);
					metadata.append("UserGroupName",userGroup.getName());
					metadata.append("authorityBefore",aidSet);
					metadata.append("authorityAfter",authorityAfter);
					atRecord.setMeta(metadata);
					auditTrailSvc.addRecord(atRecord);
				}else{
					proxyResult.setErrorCode(222072261);//此用户组没有此权限
					logger.error("[ERR222072261] 此用户组没有此权限");
				} // if..else 结束
			} // for循环结束 
			return proxyResult;
		} catch (Exception e) {//try 语句结束
			proxyResult.setErrorCode(222072270);
			logger.error("[ERR222072270] deleteUserGroupAuthority失败", ExceptionUtils.getFullStackTrace(e));
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return proxyResult;
		}
	}
	
	/**
	 * 获取权限 
	 * @param name	 权限名称
	 * @return	ServiceResult<Authority>	权限实体，Error Code
	 */
	@Override
	public ServiceResult<Authority> getAuthority(String name) {	
		ServiceResult<Authority> result=new ServiceResult<Authority>();
		try{
			Authority authority=authorityDao.getAuthority(name);
			result.setErrorCode(0);
			result.setData(authority);
			logger.info("[INF224735464] getAuthority成功！");
			return result;
		}catch(Exception e){
			result.setErrorCode(224735466);
			logger.error("[ERR224735466] name查询权限失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	}
	
	/**
	 * 根据权限id获取有这个权限的用户组
	 * @param aid	权限id
	 * @return		用户组id 的List and ErrorCode
	 */
	@Override
	public ServiceResult<List<Integer>> findUserGroupByAid(int aid) {
		ServiceResult<List<Integer>> result=new ServiceResult<List<Integer>>();
		try{
			List<Integer> userGroupList=authorityDao.findUserGroupByAid(aid);
			if(userGroupList.isEmpty()){
				result.setErrorCode(225436341);
				logger.error("[ERR225436341] 此权限ID对应的UserGroup为空");
			}else{
				result.setErrorCode(0);
				result.setData(userGroupList);
				logger.info("[INF225436412] findUserGourpByAid成功！");
			}
			return result;
		}catch(Exception e){
			result.setErrorCode(225436421);
			logger.error("[ERR225436421] findUserGourpByAid失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	}
	
	/**
	 * 查询权限名字或描述中出现关键子的记录
	 * @param str	 输入为空格分隔多关键字,多关键字间为“或”关系, 查询权限名字或描述中出现关键子的记录
	 * @return	权限ID的List and ErrorCode
	 */
	@Override
	public ServiceResult<List<Integer>> findAuthority(String str) {
		ServiceResult<List<Integer>> result=new ServiceResult<List<Integer>>();
		List<Integer> strList=new ArrayList<Integer>();
		try{
			if(str.contains(" ")||str.contains(",")||str.contains("，")){ //将字符串中符号转换成" "
				String strChange = SymbolChange.Symbol(str);
				String[] strArr = strChange.split(" ");			
				for(int i = 0;i < strArr.length; i++){
					String condition = "%"+strArr[i]+"%";
					List<Integer> list=authorityDao.findAuthority(condition);
					strList.addAll(list);
					HashSet<Integer> h = new HashSet<Integer>(strList); //去掉list里面重复元素 
					strList.clear();  
					strList.addAll(h);  
					result.setData(strList);
					result.setErrorCode(0);
					logger.info("[INF225436621] findAuthority成功！");
				}
			}else{
				String condition = "%"+str+"%";
				List<Integer> list=authorityDao.findAuthority(condition);
				strList.addAll(list);
				HashSet<Integer> h = new HashSet<Integer>(strList); //去掉list里面重复元素 
				strList.clear();  
				strList.addAll(h);  
				result.setData(strList);
				result.setErrorCode(0);
				logger.info("[INF225436621] findAuthority成功！");
			} //if..else结尾
			return result;
		}catch(Exception e){//try 语句结束
			result.setErrorCode(225436597);
			logger.error("[ERR225436597] findAuthority失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	} //方法结束
	
	/**
	 * 查询权限名字或描述中出现关键字的记录
	 * @param str	 输入为空格分隔多关键字,多关键字间为“或”关系, 查询权限名字或描述中出现关键字的记录
	 * @return	权限实体的List and ErrorCode
	 */
	public ServiceResult<List<Authority>> findAuthorityDetail(String str){
		ServiceResult<List<Authority>> result=new ServiceResult<List<Authority>>();
		List<Authority> strList=new ArrayList<Authority>();
		try{
			if(str.contains(" ")||str.contains(",")||str.contains("，")){ //将字符串中符号转换成" "
				String strChange = SymbolChange.Symbol(str);
				String[] strArr = strChange.split(" ");		
				for(int i = 0;i < strArr.length; i++){
					String condition = "%"+strArr[i]+"%";
					List<Authority> list=authorityDao.findAuthorityDetail(condition);
					strList.addAll(list);
					result.setData(strList);
					result.setErrorCode(0);
					logger.info("[INF225436621] findAuthorityDetail成功！");
				}
			}else{
				String condition = "%"+str+"%";
				List<Authority> list=authorityDao.findAuthorityDetail(condition);
				strList.addAll(list);
				HashSet<Authority> h = new HashSet<Authority>(strList); //去掉list里面重复元素 
				strList.clear();  
				strList.addAll(h);  
				result.setData(strList);
				result.setErrorCode(0);
				logger.info("[INF225436621] findAuthorityDetail成功！");
			} //if..else结尾
			return result;
		}catch(Exception e){//try 语句结束
			result.setErrorCode(225436777);
			logger.error("[ERR225436777] findAuthorityDetail失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	} //方法结束
	
	/**
	 * 根据权限id获取有这个权限的用户组
	 * @param aid	权限id
	 * @return		用户组id 的List and ErrorCode
	 */
	@Override
	public ServiceResult<List<UserGroup>> findUserGroupsByAid(int aid) {
		ServiceResult<List<UserGroup>> result=new ServiceResult<List<UserGroup>>();
		try{
			List<UserGroup> userGroupList=authorityDao.findUserGroupsByAid(aid);
			result.setErrorCode(0);
			result.setData(userGroupList);
			logger.info("[INF225436412] findUserGourpByAid成功！");
			return result;
		}catch(Exception e){
			result.setErrorCode(225436421);
			logger.error("[ERR225436421] findUserGourpByAid失败"+e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
	}

}
